/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.live.common.service.impl;

import cn.binarywang.wx.miniapp.bean.live.WxMaLiveResult;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.LiveInterfaceType;
import com.yami.shop.bean.enums.LiveProdStatusType;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.WxLiveProdResponse;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.wx.WxInterfaceUtil;
import com.yami.shop.common.wx.bean.GoodsInfoReqParam;
import com.yami.shop.common.wx.bean.UpdateGoodsInfoReqParam;
import com.yami.shop.common.wx.bean.resp.GoodsInfoRespParam;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.config.WxConfig;
import com.yami.shop.live.common.dao.LiveProdLogMapper;
import com.yami.shop.live.common.dao.LiveProdStoreMapper;
import com.yami.shop.live.common.model.LiveProdLog;
import com.yami.shop.live.common.model.LiveProdStore;
import com.yami.shop.live.common.model.LiveRoomProd;
import com.yami.shop.live.common.service.LiveLogService;
import com.yami.shop.live.common.service.LiveProdStoreService;
import com.yami.shop.live.common.service.LiveRoomProdService;
import com.yami.shop.live.common.util.WxImageUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 *
 *
 * @author LGH
 * @date 2020-08-04 16:57:17
 */
@Slf4j
@Service
@AllArgsConstructor
public class LiveProdStoreServiceImpl extends ServiceImpl<LiveProdStoreMapper, LiveProdStore> implements LiveProdStoreService {

    private final LiveProdStoreMapper liveProdStoreMapper;
    /**
     * 最大一次查询数量
     */
    private static final int MAX_COUNT = 20;
    private final WxInterfaceUtil wxInterfaceUtil;
    private final MapperFacade mapperFacade;
    private final LiveLogService liveLogService;
    private final LiveRoomProdService liveRoomProdService;
    private final ShopConfig shopConfig;
    private final WxImageUtil wxImageUtil;
    private final WxConfig wxConfig;
    private final WxInterfaceUtil wxUtil;
    private final LiveProdLogMapper liveProdLogMapper;
    private final RedissonClient redissonClient;

    private static final String REDISSON_LOCK_PREFIX = "redisson_lock:";

    @Override
    public IPage<LiveProdStore> getPage(PageParam<LiveProdStore> page, LiveProdStore liveProdStore) {
        IPage<LiveProdStore> resPage = liveProdStoreMapper.getPage(page, liveProdStore);
        List<LiveProdStore> records = resPage.getRecords();
        if(CollectionUtils.isNotEmpty(records)) {
            for (LiveProdStore record : records) {
                record.setCoverPic(shopConfig.getDomain().getResourcesDomainName() + "/" + record.getCoverPic());
            }
        }
        resPage.setRecords(records);
        return resPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitVerify(LiveProdStore liveProdStore) {
        RLock rLock = redissonClient.getLock(REDISSON_LOCK_PREFIX + "liveProdSubmitVerify" + liveProdStore.getShopId());
        try {
            if (rLock.tryLock(5,60,TimeUnit.SECONDS)) {
                // 1.校验今日可用次数并保存or修改商家次数记录
                liveLogService.checkNumsAndSaveLog(liveProdStore.getShopId(), LiveInterfaceType.ADD_PROD_AUDIT, "提交审核");
                LiveProdStore update = new LiveProdStore();
                update.setLiveProdStoreId(liveProdStore.getLiveProdStoreId());
                Date date = new Date();
                update.setUpdateTime(date);
                update.setVerifyTime(date);
                update.setStatus(LiveProdStatusType.NO_EXAMINE.value());
                // 发起微信审核, 先获取微信的media_id
                GoodsInfoRespParam goodsInfo = getInfoRespParam(liveProdStore, update);
                boolean prodStoreOk;
                boolean prodLogOk;
                // 获取到的goodsId存起来
                prodStoreOk = liveProdStoreMapper.updateById(update) > 0;
                // 添加日志
                prodLogOk = isLogOk(liveProdStore, date, goodsInfo);
                return prodStoreOk && prodLogOk;
            } else {
                // 网络异常
                throw new YamiShopBindException("yami.network.exception");
            }
        } catch (WxErrorException e) {
            log.info("获取access_token异常");
        } catch (InterruptedException e) {
            log.error("InterruptedException:", e);
        } finally {
            try {
                if (rLock.isLocked()) {
                    rLock.unlock();
                }
            } catch (Exception e){
                log.error("Exception:", e);
            }
        }
        return false;
    }

    private boolean isLogOk(LiveProdStore liveProdStore, Date date, GoodsInfoRespParam goodsInfo) {
        boolean prodLogOk;
        LiveProdLog prodLog = new LiveProdLog();
        prodLog.setLiveProdStoreId(liveProdStore.getLiveProdStoreId());
        prodLog.setUpdateTime(date);
        prodLog.setStatus(1);
        prodLog.setGoodsId(goodsInfo.getGoodsId());
        prodLog.setAuditId(goodsInfo.getAuditId());
        prodLogOk = liveProdLogMapper.insert(prodLog) > 0;
        return prodLogOk;
    }

    @NotNull
    private GoodsInfoRespParam getInfoRespParam(LiveProdStore liveProdStore, LiveProdStore update) throws WxErrorException {
        String mediaId = wxImageUtil.wxImageUpload(liveProdStore.getCoverPic());
        update.setConverImgUrl(mediaId);
        GoodsInfoReqParam reqParam = new GoodsInfoReqParam();
        reqParam.setCoverImgUrl(mediaId);
        reqParam.setName(liveProdStore.getName());
        reqParam.setPriceType(liveProdStore.getPriceType());
        reqParam.setPrice(liveProdStore.getPrice());
        reqParam.setPrice2(liveProdStore.getPrice2());
        reqParam.setUrl(liveProdStore.getUrl());
        reqParam.setAccessToken(wxConfig.getWxMaService().getAccessToken());
        GoodsInfoRespParam goodsInfo = wxUtil.prodAddVerify(reqParam);
        update.setGoodsId(goodsInfo.getGoodsId());
        update.setStatus(LiveProdStatusType.EXAMINING.value());
        return goodsInfo;
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public boolean submitVerify(LiveProdStore liveProdStore) {
//        // 1.校验今日可用次数并保存or修改商家次数记录
//        liveLogService.checkNumsAndSaveLog(liveProdStore.getShopId(), LiveInterfaceType.ADD_PROD_AUDIT, "提交审核");
//
//        LiveProdStore prodStore = new LiveProdStore();
//        prodStore.setLiveProdStoreId(liveProdStore.getLiveProdStoreId());
//        Date date = new Date();
//        prodStore.setUpdateTime(date);
//        prodStore.setVerifyTime(date);
//        prodStore.setStatus(LiveProdStatusType.NO_EXAMINE.value());
//        // 发起微信审核, 先获取微信的media_id
//        String mediaId = wxImageUtil.wxImageUpload(liveProdStore.getCoverPic());
//        WxMaLiveGoodInfo goods = mapperFacade.map(liveProdStore, WxMaLiveGoodInfo.class);
//        goods.setCoverImgUrl(mediaId);
//        WxMaLiveResult wxMaLiveResult;
//        try {
//            goods.setUrl(URLEncoder.encode(liveProdStore.getUrl(),"utf-8"));
//            wxMaLiveResult = wxConfig.getWxMaService().getLiveGoodsService().addGoods(goods);
//        }catch (Exception e){
//            throw new YamiShopBindException("yami.examine.fail");
//        }
//        prodStore.setGoodsId(wxMaLiveResult.getGoodsId());
//        prodStore.setStatus(LiveProdStatusType.EXAMINING.value());
//        boolean prodStoreOk = liveProdStoreMapper.updateById(prodStore) > 0;
//        LiveProdLog prodLog = new LiveProdLog();
//        prodLog.setLiveProdStoreId(liveProdStore.getLiveProdStoreId());
//        prodLog.setUpdateTime(date);
//        prodLog.setStatus(1);
//        prodLog.setGoodsId(wxMaLiveResult.getGoodsId());
//        prodLog.setAuditId(wxMaLiveResult.getAuditId());
//        boolean prodLogOk = liveProdLogMapper.insert(prodLog) > 0;
//        return prodStoreOk && prodLogOk;
//    }

//    /**
//     * 不需要去查询微信的入库信息，直接查询我们的数据库即可
//     * @param page 分页
//     * @param status 状态
//     * @param shopId 商家id
//     */
//    @Override
//    public PageParam<RoomResponse> listLiveProdsByStatus(PageParam<RoomResponse> page, Integer status, Long shopId) {
//        getPage()
//        WxRoomProdInfo wxRoomProdInfo = new WxRoomProdInfo();
//        wxRoomProdInfo.setOffset((page.getCurrent()-1) * page.getSize());
//        wxRoomProdInfo.setLimit(page.getSize());
//        wxRoomProdInfo.setStatus(status);
//        WxServerResponse<PageParam<RoomResponse>> pageParamWxServerResponse = wxUtil.pageLivePords(wxRoomProdInfo);
//        if(!pageParamWxServerResponse.isSuccess()){
//            throw new YamiShopBindException("获取微信入库商品失败！");
//        }
//        return null;
//    }

    @Override
    public IPage<LiveProdStore> pageProdByRoomId(PageParam<LiveProdStore> page, Integer roomId) {
        IPage<LiveProdStore> liveProdStorePage = liveProdStoreMapper.pageProdByRoomId(page, roomId);
        List<LiveProdStore> records = liveProdStorePage.getRecords();
        if(CollectionUtils.isNotEmpty(records)) {
            for (LiveProdStore record : records) {
                record.setCoverPic(shopConfig.getDomain().getResourcesDomainName() + "/" + record.getCoverPic());
            }
        }
        liveProdStorePage.setRecords(records);
        return liveProdStorePage;
    }

    @Override
    public void synchronousWxLiveProds() throws WxErrorException{
        List<LiveProdStore> liveProdStores = list(new LambdaQueryWrapper<LiveProdStore>().ne(LiveProdStore::getStatus,LiveProdStatusType.DELETE.value()));
        List<Integer> ids = new ArrayList<>();
        liveProdStores.forEach(liveProdStore -> {
            if(Objects.nonNull(liveProdStore.getGoodsId())){
                ids.add(liveProdStore.getGoodsId());
            }
        });
        WxMaLiveResult wxMaLiveResult;
        List<WxMaLiveResult.Goods> goods = new ArrayList<>();
        try {
            int count = (int)Math.ceil(Arith.div(ids.size(),20));
            for (int i = 0; i < count; i++) {
                List<Integer> goodsIds = new ArrayList<>();
                int maxLength = Math.min(MAX_COUNT * (i + 1),ids.size());
                for (int j = MAX_COUNT * i ; j < maxLength; j++) {
                    goodsIds.add(ids.get(j));
                }
                wxMaLiveResult = wxConfig.getWxMaService().getLiveGoodsService().getGoodsWareHouse(goodsIds);
                goods.addAll(wxMaLiveResult.getGoods());
            }
        }catch (WxErrorException e){
            log.error("获取直播间商品状态失败！");
            log.error(e.getMessage());
            return;
        }

        Date date = new Date();
        if(CollectionUtils.isEmpty(goods)){
            return;
        }
        Map<Integer, Integer> wxGoodsMap = goods.stream().collect(Collectors.toMap(WxMaLiveResult.Goods::getGoodsId, WxMaLiveResult.Goods::getAuditStatus));
        for (LiveProdStore liveProdStore : liveProdStores) {
            if(Objects.isNull(liveProdStore.getGoodsId()) || !wxGoodsMap.containsKey(liveProdStore.getGoodsId()) || Objects.isNull(wxGoodsMap.get(liveProdStore.getGoodsId()))){
                continue;
            }
            Integer status = wxGoodsMap.get(liveProdStore.getGoodsId());
            // 从任意非审核通过的状态变成审核通过，修改审核时间
            if(!Objects.equals(liveProdStore.getStatus(),status) &&
                    Objects.equals(status,LiveProdStatusType.EXAMINE_SUCCESS.value())){
                liveProdStore.setSuccessTime(date);
            }
            liveProdStore.setStatus(status);
        }
        // 批量修改商品状态
        updateBatchById(liveProdStores);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeWxLiveProdById(Long liveProdStoreId, long shopId) {
        LiveProdStore liveProdStore = getById(liveProdStoreId);
        // 移除数据库的数据包括关联
        update(new LambdaUpdateWrapper<LiveProdStore>().set(LiveProdStore::getStatus,-1).eq(LiveProdStore::getLiveProdStoreId,liveProdStoreId));
        liveRoomProdService.remove(new LambdaQueryWrapper<LiveRoomProd>().eq(LiveRoomProd::getProdStoreId,liveProdStoreId));
        // 状态为审核通过的商品进行移除微信商品库的数据、扣除次数
        if(Objects.equals(liveProdStore.getStatus(),LiveProdStatusType.EXAMINE_SUCCESS.value())){
            // 1.校验今日可用次数并保存or修改商家次数记录
            liveLogService.checkNumsAndSaveLog(shopId, LiveInterfaceType.DELETE_PROD, "删除商品库商品");
            try{
                wxConfig.getWxMaService().getLiveGoodsService().deleteGoods(liveProdStore.getGoodsId());
            }catch (Exception e){
                log.error("删除微信直播商品失败！",liveProdStore.getGoodsId());
                log.error(e.getMessage());
                throw new YamiShopBindException("yami.live.prod.delete.fail");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWxLiveProdById(LiveProdStore liveProdStore) throws WxErrorException{
        // 两种情况修改
        // 没有提交微信商品库的修改
        if(Objects.isNull(liveProdStore.getProdId())){
            throw new YamiShopBindException("yami.score.select.num");
        }
        if(Objects.equals(liveProdStore.getStatus(), LiveProdStatusType.NO_EXAMINE.value())){
            updateById(liveProdStore);
        }
        if(Objects.equals(liveProdStore.getStatus(), LiveProdStatusType.EXAMINING.value())){
            // 商品正在审核中，无法进行修改
            throw new YamiShopBindException("yami.live.prod.examine");
        }
        if(Objects.equals(liveProdStore.getStatus(), LiveProdStatusType.EXAMINE_SUCCESS.value())){
            // 1.校验今日可用次数并保存or修改商家次数记录
            liveLogService.checkNumsAndSaveLog(liveProdStore.getShopId(), LiveInterfaceType.UPDATE_PROD, "修改商品库商品");

            // 提交到微信商品库的修改
            LiveProdStore prodStore = new LiveProdStore();
            prodStore.setPrice(liveProdStore.getPrice());
            prodStore.setPrice2(liveProdStore.getPrice2());
            prodStore.setGoodsId(liveProdStore.getGoodsId());
            prodStore.setUpdateTime(liveProdStore.getUpdateTime());
            prodStore.setPriceType(liveProdStore.getPriceType());
            updateById(liveProdStore);
            // 修改微信商品库
            UpdateGoodsInfoReqParam goodsInfo = mapperFacade.map(prodStore,UpdateGoodsInfoReqParam.class);
            goodsInfo.setAccessToken(wxConfig.getWxMaService().getAccessToken());
            WxLiveProdResponse<Void> liveProdResponse = wxInterfaceUtil.prodUpdate(goodsInfo);
            if(!liveProdResponse.isSuccess()){
                // 更新直播商品库失败
                throw new YamiShopBindException("yami.live.prod.update.fail");
            }
        }
    }

    /**
     * 移除十天前旧的上架商品
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeOldLiveProd() throws WxErrorException{
        // 十天前的时间
        DateTime dateTime = DateUtil.offsetDay(new Date(), -10);
        Date date = new Date();
        // 查询十天前上架的商品
        List<LiveProdStore> prodStoreList = list(new LambdaQueryWrapper<LiveProdStore>().eq(LiveProdStore::getStatus, LiveProdStatusType.EXAMINE_SUCCESS.value())
                .le(LiveProdStore::getSuccessTime, dateTime));
        if(CollectionUtils.isEmpty(prodStoreList)){
            return;
        }
        List<Long> ids = new ArrayList<>();
        for (LiveProdStore liveProdStore : prodStoreList) {
            liveProdStore.setCancelTime(date);
            liveProdStore.setStatus(LiveProdStatusType.PLATFORM_BREAK.value());
            ids.add(liveProdStore.getLiveProdStoreId());
            try {
                // 移除微信商品库的数据
                wxConfig.getWxMaService().getLiveGoodsService().deleteGoods(liveProdStore.getGoodsId());
                boolean deleteGoods = wxConfig.getWxMaService().getLiveGoodsService().deleteGoods(liveProdStore.getGoodsId());
                if (!deleteGoods) {
                    // 删除直播商品失败
                    throw new Exception();
                }
            }catch (Exception e){
                log.error("删除直播商品失败！",liveProdStore.getGoodsId());
                log.error(e.getMessage());
            }
        }
        // 批量修改
        liveProdStoreMapper.updateBatch(prodStoreList);
        // 删除直播间和商品的关联
        liveRoomProdService.remove(new LambdaQueryWrapper<LiveRoomProd>().in(LiveRoomProd::getProdStoreId,ids));
    }
}
